#import "ALSourceListViewController.h"
#import <SMRColumnView/SMRColumnEntry.h>
#import "ALVersion.h"
#import "ALApp.h"
#import "ALSourceListAppView.h"
#import "NSManagedObjectContext+SMRAdditions.h"
#import "NSManagedObject+SMRAdditions.h"
#import "ALMainWindowController.h"
#import "ALAppInfoPopoverController.h"
#import "NSObject+BlockObservation.h"


static const CGFloat ALSourceListEntryTopPadding = 58.0f;


@implementation ALSourceListViewController

@synthesize sourceListColumnView;
@synthesize sourceListEntryPrototype;
@synthesize managedObjectContext;
@synthesize mainWindowController;
@synthesize appInfoPopoverViewController;
@synthesize appInfoPopover;
@synthesize appsArrayController;


-(void)awakeFromNib {
    [[self sourceListColumnView] setAllowsMultipleSelection:YES];
    [[self sourceListColumnView] setAllowsEmptySelection:NO];
    [[self sourceListColumnView] setDrawsHighlight:NO];
    [[self sourceListColumnView] setAnimated:NO];
    [[self sourceListColumnView] bind:SMRColumnViewContentBinding toObject:[self appsArrayController] withKeyPath:ALArrangedObjectsKey options:nil];
    [[self sourceListEntryPrototype] setSelectable:YES];
    [[self sourceListEntryPrototype] setTopPadding:ALSourceListEntryTopPadding];

	// Temporarily observe the source lists' child entries to initialize selection once bindings are established
	[[self sourceListColumnView] addObserver:self forKeyPath:@"childEntries" options:0 context:NULL];
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
	// Temporarily observing the source lists' child entries to initialize selection once bindings are established
	if ([[[self sourceListColumnView] childEntries] count] == 0)
		return;
	
	[[self sourceListColumnView] removeObserver:self forKeyPath:@"childEntries"];
	NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
	[noteCenter addObserver:self selector:@selector(sourceListSelectionDidChange:) name:SMRColumnViewSelectionDidChangeNotification object:[self sourceListColumnView]];	

	NSArray *objectURIStrings = [[NSUserDefaults standardUserDefaults] arrayForKey:kALSelectedAppsKey];
	NSArray *selectedApps = [[self managedObjectContext] smrObjectsWithURIStrings:objectURIStrings];
    NSMutableArray *selectedAppEntries = [NSMutableArray arrayWithCapacity:[selectedApps count]];
    for (NSManagedObject *selectedApp in selectedApps) {
        SMRColumnEntry *selectedAppEntry = [[self sourceListColumnView] entryWithRepresentedObject:selectedApp];
        [selectedAppEntries addObject:selectedAppEntry];
    }
	if ([selectedAppEntries count] == 0) {
        SMRColumnEntry *firstAppEntry = [[[self sourceListColumnView] childEntries] objectAtIndex:0];
		[selectedAppEntries addObject:firstAppEntry];
    }
	[[self sourceListColumnView] selectEntries:selectedAppEntries extendSelection:NO];
}


#pragma mark -
#pragma mark Accessors

-(NSViewController *)appInfoPopoverViewController {
    if (!appInfoPopoverViewController) 
        appInfoPopoverViewController = [[ALAppInfoPopoverController alloc] initWithNibName:@"AppInfoPopover" bundle:[NSBundle mainBundle] windowController:nil managedObjectContext:[self managedObjectContext]];
    return appInfoPopoverViewController;
}

-(NSPopover *)appInfoPopover {
    if (!appInfoPopover) {
        appInfoPopover = [[NSPopover alloc] init];
        [appInfoPopover setContentViewController:[self appInfoPopoverViewController]];
        [appInfoPopover setBehavior:NSPopoverBehaviorTransient];
    }
    return appInfoPopover;
}


#pragma mark -
#pragma mark Actions

-(IBAction)appInfoPopover:(id)sender {
    SMRColumnEntry *clickedEntry = [[self sourceListColumnView] entryWithView:sender];
    if (!clickedEntry)
        return;
    ALApp *clickedApp = [clickedEntry representedObject];
    [[self appInfoPopoverViewController] view];
    [[self appInfoPopoverViewController] setRepresentedObject:clickedApp];
    [[self appInfoPopover] showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMaxXEdge];
}


#pragma mark -
#pragma mark Source list column view delegate

-(NSView *)columnView:(SMRColumnView *)aColumnView willForwardHitTestAtPoint:(NSPoint)aPoint toSubview:(NSView *)subview {
    if (aColumnView != [self sourceListColumnView])
        return nil;
    if ([subview isKindOfClass:[NSButton class]])
        return subview;
    return nil;
}


#pragma mark -
#pragma mark Notifications

-(void)sourceListSelectionDidChange:(NSNotification *)note {
	NSArray *selectedObjects = [[self sourceListColumnView] selectedObjects];
    NSArray *objectURIs = [selectedObjects valueForKey:@"smrURIRepresentation"];
    NSArray *objectURIStrings = [objectURIs valueForKeyPath:@"absoluteString"];
    [[NSUserDefaults standardUserDefaults] setObject:objectURIStrings forKey:kALSelectedAppsKey];
}

+(NSSet *)keyPathsForValuesAffectingSelectedApp {
	return [NSSet setWithObject:@"sourceListColumnView.selectedObject"];
}

-(ALApp *)selectedApp {
	return [[self sourceListColumnView] selectedObject];
}

@end
